﻿using System;
using Microsoft.SPOT;
using NetduinoGo;
using GoBus;
using System.IO.Ports;

namespace NetduinoGo.Modules.PeteBrown
{
    public class MidiMessageRecievedEventArgs : EventArgs
    {
        public MidiMessage Message { get; internal set; }
    }


    public partial class MidiModule : GoModule
    {
        private SerialPort _serial;

        public delegate void MidiMessageReceivedEventHandler(MidiModule sender, MidiMessageRecievedEventArgs args);

        /// <summary>
        /// Fires whenever a MIDI message is received. Don't do anything too time consuming in here, or
        /// you'll tie up the MIDI processing loop.
        /// </summary>
        public event MidiMessageReceivedEventHandler MessageReceived;


        public MidiModule(string portName)
        {
            _serial = new SerialPort(portName, 31250, Parity.None, 8, StopBits.One);

            ActiveSenseMode = MidiActiveSenseMode.AutomaticallyRespond;

            AutoFlushSerialOutput = false;

            // open ze port
            _serial.Open();

        }




        private void DispatchMessage(MidiMessage message)
        {
            // raise event

            // TODO: Should do this asynchronously so we don't tie up the processing with long-running user code

            //DebugPrint("MIDI Message: " + message.ID.ToString());

            if (MessageReceived != null)
                MessageReceived(this, new MidiMessageRecievedEventArgs() { Message = message });

        }

        private const int MaxBufferSize = 128;
        private byte[] _buffer = new byte[MaxBufferSize];

        // Loads incoming data from the serial port to the buffer.
        private void OnSerialDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (e.EventType == SerialData.Chars)
            {
                int count = 0;

                //lock (_buffer)
                //{
                count = _serial.Read(_buffer, 0, _serial.BytesToRead > MaxBufferSize ? MaxBufferSize : _serial.BytesToRead);

                // performance of this needs to be monitored to see if
                // it holds up with other tasks going on
                if (SoftThru)
                {
                    _serial.Write(_buffer, 0, count);
                    _serial.Flush();
                }

                ParseBuffer(count);
                //}

            }
            else if (e.EventType == SerialData.Eof)
            {
                // TODO
            }
        }

    }
}
